#ifndef AER_RENDERBUFFER_HPP_
#define AER_RENDERBUFFER_HPP_

#include "aerDeviceResource.hpp"
#include "aerTexture.hpp"


namespace aer {
  
class Renderbuffer : public DeviceResource
{
  private:
    static const unsigned int kDefaultSize = 32u;//
    
  private:
    int m_internalFormat;
    unsigned int m_width;
    unsigned int m_height;
    

  public:
    Renderbuffer()
          : DeviceResource(),
            m_internalFormat(GL_DEPTH_COMPONENT),//
            m_width(kDefaultSize),
            m_height(kDefaultSize)
    {}
    
    void generate()
    {
      AER_ASSERT( !isGenerated() );
      glGenRenderbuffers( 1, &m_id);
    }
    
    void release() 
    {
      if (isGenerated()) 
      {
        glDeleteRenderbuffers( 1, &m_id);
        m_id = 0u;
      }
    }
      
    void bind() 
    {
      glBindRenderbuffer( GL_RENDERBUFFER, m_id); 
    }
    
    static void unbind() 
    {
      glBindRenderbuffer( GL_RENDERBUFFER, 0u); 
    }
    

    // ===========
    // + Getters +
    // ===========

    int getInternalFormat()
    {    
      return m_internalFormat;
    }    

    
    // ===========
    // + Setters +
    // ===========
    // !! Care must be taken to specify parameters before binding 
    // !! the Renderbuffer
    
    void setInternalFormat(int internalFormat)
    {
      m_internalFormat = internalFormat;
      rebuild();
    }
    
    void resize(unsigned int width, unsigned int height)
    {
      m_width = width;
      m_height = height;
      rebuild();
    }
    
    void resize(unsigned int width, unsigned int height, 
                int internalFormat)
    {
      m_internalFormat = internalFormat;
      m_width = width;
      m_height = height;
      rebuild();
    }
    
    private:
      void rebuild()
      {
        bind();
        glRenderbufferStorage( GL_RENDERBUFFER, m_internalFormat, m_width, m_height);
        unbind();
      }
};
  
} // aer

#endif // AER_RENDERBUFFER_HPP_
